package com.xmly;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.worktool.RestExecutor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;

public class Start {

    public static final Logger log = LoggerFactory.getLogger(Start.class);

    private RestTemplate restTemplate = RestExecutor.buildNew();

    private static final String device_id_type = "UUID";

    private static String device_id = "RuoYouShiWu";

    private static final String app_key =  "aad2049ec57c41adb790833222f945a5";

    private static final String app_secret =  "5CB59794B335551371AFC9E3513B0D91";

    private static final String sn =  "11984_00_100984";

    private static final String version =  "v_0.0.1";

    private static final String host = "https://api.ximalaya.com/ximalayaos-openapi-xm";

    /**
     * 公共参数
     * */
    public static Map<String,Object> getComParams(String userid){
        Map<String,Object> comParams = new LinkedHashMap<>();
        comParams.put("app_key",app_key);//小雅智能商务平台应用公钥
        comParams.put("client_os_type",3);//1-iOS；2-Android；3-Web(API接入) ；4-Linux；5-ecos；6-qnix；17-rtos；18=小程序；19=H5
        comParams.put("device_id",userid);//设备ID号(参考设备ID生成算法说明)
        comParams.put("sn",sn);//在小雅智能商务平台创建产品生成的sn码

        comParams.put("nonce",UUID.randomUUID());//一个随机字符串，随机性越大越好，每个请求都需要重新生成
        comParams.put("timestamp",System.currentTimeMillis());//当前Unix毫秒数时间戳，每个请求都需要重新生成
        comParams.put("device_id_type",device_id_type);//device_id设备唯一标识字段类型，主要有以下六种设备标识类型：OAID、OAID_MD5、Android_ID、Android_ID_MD5、IDFA、 IDFA_MD5、UUID，请参考设备ID生成算法
        //comParams.put("version",version);//版本号
        return comParams;
    }


    public Map<String,Object> testParams(){
        Map<String,Object> comParams = new LinkedHashMap<>();
        comParams.put("page",1);
        comParams.put("count",3);
        comParams.put("city_code","4403");
        comParams.put("app_key","b971adfc4fb44632b2e5885f1653db88");//小雅智能商务平台应用公钥
        comParams.put("client_os_type",3);//1-iOS；2-Android；3-Web(API接入) ；4-Linux；5-ecos；6-qnix；17-rtos；18=小程序；19=H5
        comParams.put("device_id","d123");//设备ID号(参考设备ID生成算法说明)
        comParams.put("device_id_type","UUID");//device_id设备唯一标识字段类型，主要有以下六种设备标识类型：OAID、OAID_MD5、Android_ID、Android_ID_MD5、IDFA、 IDFA_MD5、UUID，请参考设备ID生成算法
        comParams.put("nonce","ODu26wVOoD");//一个随机字符串，随机性越大越好，每个请求都需要重新生成
        comParams.put("sn","11899_00_100899");//在小雅智能商务平台创建产品生成的sn码
        comParams.put("timestamp",1665198401059L);//当前Unix毫秒数时间戳，每个请求都需要重新生成
        comParams.put("sig","0601fbcff6eae4413d7f0d5fb61779a6");
        return comParams;
    }

    public static void main(String[] args) {
        Start start = new Start();
        start.todayHot();
        start.lmList();

    }

    public static String getSig(Map<String, String> param) {
        TreeMap<String, String> sortParam = new TreeMap<>(param);
        String assemble = sortParam.entrySet().stream()
                .map(x -> x.getKey() + "=" + x.getValue())
                .collect(Collectors.joining("&"));
        String base64 = Base64.getEncoder().encodeToString(assemble.getBytes(StandardCharsets.UTF_8));
        String sign = SecureUtil.md5().digestHex(SecureUtil.hmacSha1(app_secret).digest(base64));
        return sign;
    }

    private static String sig(Map<String,Object> params){

        TreeMap<String, Object> sortParam = new TreeMap<>(params);
        String assemble = sortParam.entrySet().stream()
                .map(x -> x.getKey() + "=" + x.getValue())
                .collect(Collectors.joining("&"));

        // 将字符串编码为字节数组，并使用 UTF-8 字符集
        byte[] bytes = assemble.getBytes(StandardCharsets.UTF_8);

        // 对字节数组进行 Base64 编码
        String base64Encoded = Base64.getEncoder().encodeToString(bytes);
        byte[] sha1 = SHA1(app_secret,base64Encoded);
        return MD5(sha1);
    }

    /**
     * @param app_secret 哈希key
     * @param base64EncodedStr 文本值
     * */
    private static byte[] SHA1(String app_secret,String base64EncodedStr){
        try {
            // 创建秘钥对象
            SecretKeySpec secretKeySpec = new SecretKeySpec(app_secret.getBytes(), "HmacSHA1");
            // 创建 HMAC-SHA1 算法实例
            Mac mac = Mac.getInstance("HmacSHA1");
            // 初始化 HMAC 算法实例，传递秘钥
            mac.init(secretKeySpec);
            // 计算消息的哈希值
            return mac.doFinal(base64EncodedStr.getBytes(StandardCharsets.UTF_8));
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            e.printStackTrace();
            log.error("SHA1失败："+e.getMessage());
        }
        return null;
    }

    /**
     * 使用 HMAC-SHA1 签名方法对对encryptText进行签名
     * @param encryptText 被签名的字符串
     * @param encryptKey  密钥
     * @return
     * @throws Exception
     */
    public static byte[] HmacSHA1Encrypt(String encryptKey, String encryptText)
    {
        try {
            //根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
            SecretKey secretKey = new SecretKeySpec(encryptKey.getBytes(StandardCharsets.UTF_8), "HmacSHA1");
            //生成一个指定 Mac 算法 的 Mac 对象
            Mac mac = Mac.getInstance("HmacSHA1");
            //用给定密钥初始化 Mac 对象
            mac.init(secretKey);

            byte[] text = encryptText.getBytes(StandardCharsets.UTF_8);
            //完成 Mac 操作
            return mac.doFinal(text);
        }catch (Exception e){
            e.printStackTrace();
            log.error("HmacSHA1 失败："+e.getMessage());
        }
        return null;
    }

    private static String MD5(byte[] sha1ResultBytes){
        // 创建 MD5 消息摘要对象
        try {
            MessageDigest md5Digest = MessageDigest.getInstance("MD5");
            // 计算哈希值
            byte[] md5HashBytes = md5Digest.digest(sha1ResultBytes);

            // 将哈希值转换为十六进制字符串
            StringBuilder hexString = new StringBuilder();
            for (byte b : md5HashBytes) {
                String hex = Integer.toHexString(0xFF & b);
                if (hex.length() == 1) {
                    hexString.append('0');
                }
                hexString.append(hex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            log.error("MD5失败："+e.getMessage());
        }
        return null;
    }

    /**
     * 今日热点
     * */
    public void todayHot(){
        String path = "/bff/scenes/today_news/channels";
        String url = host + path;

        Map<String,Object> params = this.getComParams("RuoYouShiWu");

        String sin = sig(params);
        params.put("sig",sin);

        UriComponentsBuilder uri = this.builderUrl(url,params);
        JSONArray arr = restTemplate.getForObject(uri.toUriString(),JSONArray.class);
        System.err.println(arr);
    }


    /**
     * 栏目列表
     * */
    public void lmList(){
        String path = "/live/get_radios_by_city";
        String url = host + path;

        Map<String,Object> params = this.getComParams("RuoYouShiWu");


        params.put("page",1);
        params.put("count",1);
        params.put("city_code",4403);




        String sig = sig(params);


        params.put("sig",sig);


        UriComponentsBuilder uri = this.builderUrl(url,params);

        Object arr = restTemplate.getForObject(uri.toUriString(),Object.class);
        System.err.println(arr);
    }

    private UriComponentsBuilder builderUrl(String url,Map<String,Object> params){
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        for(Map.Entry<String, Object> entry: params.entrySet()){
            builder.queryParam(entry.getKey(),entry.getValue());
        }
        System.err.println("url:"+builder.toUriString());
        return builder;
    }

    /**
     * @param value 原始值
     * */
    private static String urlEncoder(String value){

        if(StringUtils.isNotBlank(value)){
            // 使用 URLEncoder 对参数进行编码
            try {
                String encodedString = URLEncoder.encode(value, "UTF-8");
                return encodedString;
            } catch (Exception e) {
                System.err.println("urlEncoder失败："+e.getMessage());
                e.printStackTrace();
            }
        }

        return null;
    }

}
